(function () {
    'use strict';
    if (window.bridge) {
        console.log('bridge already exists!!!');
        return;
    }

    var bridge = {};

    /**
     * 注册通知
     */
    bridge.registerNotification = function (name, func) {
        var notifications = this.notifications || {};
        notifications[name] = func;
        this.notifications = notifications;
    };

    /**
     * 处理通知
     */
    bridge.handleNotify = function (name, data) {
        var notifications = this.notifications || {};
        var func = notifications[name];
        if (typeof func === 'function') {
            func(data);
        }
    };

    /**
     * 注册函数
     */
    bridge.register = function (name, func) {
        var functions = this.functions || {};
        functions[name] = func;
        this.functions = functions;
    };

    /**
     * 处理函数调用
     */
    bridge.handleFunctionCall = function (name, data, callbackId) {
        var functions = this.functions || {};
        var func = functions[name];
        if (typeof func === 'function') {
            func(data, function (data) {
                bridge.channel.src = 'bridge://callback?callbackId=' + callbackId + '&data=' + encodeURIComponent(data);
            });
        }
    };

    /**
     * 调用原生函数
     */
    bridge.call = function (name, data, callback) {
        var callbackId = new Date().getTime();
        var callbacks = this.callbacks || {};
        callbacks[callbackId] = callback;
        this.callbacks = callbacks;
        this.channel.src = 'bridge://call?name=' + name + '&data=' + encodeURIComponent(data) + '&callbackId=' + callbackId;
    };

    /**
     * 原生函数的回调
     */
    bridge.handleCallback = function (callbackId, data) {
        var callbacks = this.callbacks || {};
        var callback = callbacks[callbackId];
        if (typeof callback === 'function') {
            callback(data);
            delete callbacks[callbackId];
            this.callbacks = callbacks;
        }
    };

    var channel = document.createElement('iframe');
    channel.style.display = 'none';
    document.documentElement.appendChild(channel);
    bridge.channel = channel;

    window.bridge = bridge;

    var readyEvent = document.createEvent('CustomEvent');
    readyEvent.initCustomEvent('bridge', true, false, bridge);
    document.dispatchEvent(readyEvent);
})();